package com.study.fileCheck;


import java.io.*;

/**
 * 读入已经有序的记录
 */
public class SortedFileReader extends FileReader {

    File file;
    LineNumberReader reader;
    String symbol;
    int size;
    int line = -1; // 当前数据行号

    /**
     * 指定需要读取的有序文件和文件的列数
     * <p>
     * 默认文件字段分割符为","
     *
     * @param file 有序文件对象
     * @param size 文件列数
     * @throws Exception
     */
    public SortedFileReader(File file, int size) throws Exception {
        if (file == null) {
            throw new NullPointerException("File \"file\" is null");
        }
        if (!file.isFile()) {
            throw new IllegalArgumentException("File \"file\" is illegal");
        }
        this.file = file;
        reader = new LineNumberReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
        this.size = size;
        this.symbol = ",";
    }

    /**
     * 设置文件的字段分隔符
     *
     * @param symbol 分隔符
     */
    @Override
    public void setSymbol(String symbol) {
        this.symbol = symbol;
    }

    /**
     * 获取当前行号
     *
     * @return 当前阅读的文件行号
     */
    public int getLine() {
        return line;
    }

    /**
     * 获取下一条文件记录
     *
     * @return 分割完成的数据
     * @throws Exception
     */
    private String[] nextRecord() throws Exception {
        for (; ; ) {
            String s = reader.readLine();
            if (s == null) {
                return null;
            }

            s = s.trim();
            if (s.isEmpty()) {
                continue;
            }
            line = reader.getLineNumber();

            String[] r = s.split(symbol, -1);
            if (r.length != size) {
                throw new Exception(String.format("文件格式错误: %s(%d): %s", file.getName(), line, s));
            }

            return r;
        }
    }

    @Override
    public void close() throws Exception {
        if (reader != null) {
            try {
                reader.close();
            } catch (Exception e) {
            }
        }
    }

    @Override
    public String[] read() throws Exception {
        return nextRecord();
    }
}

